<?php

namespace LhpAmis\Plugin\FormBuilder;

use LhpAmis\Renderers\Amis;
use LhpAmis\Renderers\BaseApi;
use LhpAmis\Renderers\BaseRenderer;
use LhpAmis\Renderers\Form;
use LhpAmis\Renderers\GroupControl;
use LhpAmis\Traits\BaseApiTrait;
use LhpAmis\Traits\ButtonsTrait;

class FormBuilder extends Form
{
    use BaseApiTrait;
    use ButtonsTrait;

    protected array $body = [];
    protected array $data = [];
    protected object $form;
    protected string $primaryKey = 'id';
    protected bool $is_filter = false;
    protected array $actions = [];
    protected array $fieldIsRequired = [];
    /**
     * @var bool 是否组合分组
     */
    private $is_group = false;
    public function __construct()
    {
        parent::__construct();
        $this->setApi($this->BaseApiPost());
        $this->set('title', '');
        $this->mode('horizontal');
    }
    public function isFilter($isFilter = true)
    {
        $this->is_filter = $isFilter;
        return $this;
    }

    public function setTitle($value)
    {
        $this->set('title', $value);
        return $this;
    }
    protected BaseApi $api;

    /**
     * @param BaseApi $api
     * @return $this
     */
    public function setApi(BaseApi $api): FormBuilder
    {
        $this->api = $api;
        return $this;
    }

    /**
     * 设置提交按钮
     * @param string $label 按钮名称
     * @param array $extend_attr 扩展属性
     * @param string $url 请求地址
     * @param array $vars 请求参数
     * @param bool $suffix 是否添加后缀
     * @param bool $domain 是否添加域名
     * @return $this
     */
    public function setSubmitAction($label = '保存', $extend_attr = [], $url = '', array $vars = [], $data = [], $type = 'form')
    {
        if (is_object($label)) {
            $items = $label;
        } else {
            if (is_string($url)) {
                if (!$this->containsAny($url, ['get:', 'post:', 'put:', 'delete:'])) {
                    $url = $this->BaseApiPost($url, [$vars], $data, $type);
                }
            }

            $items = Amis::make()->Action()->label($label)->actionType('ajax')->api($url);
        }
        $this->extend_attr($items, $extend_attr);
        $this->actions[] = $items;
        return $this;
    }

    public function setFilterSubmitAction()
    {
        $this->actions[] = ["type" => "submit", "label" => "查询", 'level' => 'primary'];
        return $this;
    }
    public function setResetAction()
    {
        $this->actions[] = ["type" => "reset", "label" => "重置", 'level' => 'primary'];
        return $this;
    }
    private function containsAny($string, $array)
    {
        foreach ($array as $value) {
            if (strpos($string, $value) !== false) {
                return true;
            }
        }
        return false;
    }

    private function buildBody()
    {
        $ComponentArray = [];
        foreach ($this->body as $body) {
            if (is_object($body) && is_a($body, Amis::class)) {
                $ComponentArray[] = $body;
            } elseif (is_array($body)) {
                $ComponentArray[] = $body;
                GroupControl::make()->body($body);
            } else {
                $ComponentArray[] = $this->formBuildField($body, $this->is_filter);
            }
        }
        return $ComponentArray;
    }
    private function formNameField(&$nameFiled, &$type)
    {
        $nameFiled = $this->is_filter ? $nameFiled . '$filter|' . $type : $nameFiled;

        if (strpos($nameFiled, '.*') !== false) {
            $nameFiled = str_replace('.*', '', $nameFiled);
            $this->fieldIsRequired[$nameFiled] = true;
        } else {
            $this->fieldIsRequired[$nameFiled] = false;
        }
        return $nameFiled;
    }
    public function formBuildField($item, $is_filter = false)
    {
        // try {
        //     $item['name'];
        // } catch (\Throwable $th) {
        //    dump($item);die;
        // }
        if (is_object($item) && $item instanceof BaseRenderer) {
            return $item;
        } elseif (is_object($item['name']) && $item['name'] instanceof BaseRenderer) {
            $Component = $item['name'];
            $name = $this->formNameField($Component->get('name'), $Component->get('type'));
        } else {
            $name = $item['name'];
            $map = $this->getBuilderMaps();

            if (isset($map['input-' . $item['type']])) {
                $ComponentClass = $map['input-' . $item['type']];
            } elseif (isset($map[$item['type']])) {
                $ComponentClass = $map[$item['type']];
            } else {
                throw new \Exception('未找到组件' . $item['type']);
            }
            if ($is_filter && in_array($item['type'], ['time', 'datetime', 'date', 'month', 'quarter', 'year'])) {
                if (isset($map['input-' . $item['type'] . '-range'])) {
                    $ComponentClass = $map['input-' . $item['type'] . '-range'];
                }
            }

            if (class_exists($ComponentClass)) {
                $Component = $ComponentClass::make();
            } else {
                throw new \Exception('未找到组件' . $ComponentClass);
            }
        }

        //判断并设置字段名称
        if ($name !== '') {
            $Component->name($name);
        }

        //判断并设置字段标签
        if ($item['label'] !== '') {
            $Component->label($item['label']);
        }

        //判断并设置描述
        if ($item['description'] !== '') {
            $Component->label($item['description']);
        }

        //判断默认值是否为空并且当前组件有value方法设置默认值
        if (isset($item['value']) && method_exists($Component, 'value')) {
            $Component->value($item['value']);
        }

        //判断是否必填,并且不是表单筛选器
        if ($this->fieldIsRequired[$name]) {
            $Component->required($this->fieldIsRequired[$name]);
        }
        //根据组件特性设置组件属性
        $Component->formBuildField($item, $is_filter);
        return $Component;
    }
    public function filteredResults(): array
    {
        $this->api($this->api);
        $this->body($this->buildBody());
        if (!empty($this->options)) {
            $this->actions($this->actions);
        }
        if ($this->is_filter) {
            $this->unset('api');
        }
        return $this->toArray();
    }


    /**
     * @param string|array|object $name
     * @param string $label
     * @param string $type
     * @param string $description
     * @return $this
     */
    public function addFormItem($name, string $label = '', string $type = 'text', string $description = '', $value = '')
    {

        if (is_array($name)) {
            $body = [];
            foreach ($name as $item) {
                if (is_array($item)) {
                    $body[] = $this->addFormItem(...$item);
                } elseif (is_object($item)) {
                    $body[] = $item;
                }
            }

            $items = ['label' => $label, 'type' => 'group', 'body' => $body];

            // $items = array_merge($items, array_slice(func_get_args(), 2));
            $items = Amis::make()->GroupControl('', $label)->body($body);
        } elseif (is_object($name)) {
            $items = $name;
        } else {

            $typeAttrArray = [];
            if (is_string($type) && strpos($type, ':') !== false) {
                $typeAndAttr = explode(':', $type);
                $type = $typeAndAttr[0];

                if (strpos($typeAndAttr[1], '/') !== false) {

                    $typeAttrArray['source'] = $typeAndAttr[1];
                }
            }

            $this->formNameField($name, $type);

            $items = ['name' => $name, 'label' => $label, 'type' => $type, 'description' => $description, 'value' => $value];

            $items = array_merge($items, array_slice(func_get_args(), 5), $typeAttrArray);

            $items = $this->formBuildField($items, $this->is_filter);
        }

        if ($this->is_group) {
            return $items;
        }
        $this->body[] = $items;
        return $this;
    }

    public function setBodys($body)
    {
        $this->body = array_merge($this->body, $body);
        return $this;
    }
    /**
     * 设置扩展属性
     * @param mixed $items
     * @param array $extend_attr
     */
    protected function extend_attr(&$items, array $extend_attr = [])
    {
        foreach ($extend_attr as $key => $value) {
            $items->set($key, $value);
        }
        return $items;
    }

    /**
     * @param array $items
     * @return $this
     */
    public function addFormItems(array $items = []): FormBuilder
    {
        foreach ($items as $options) {
            if (gettype(reset($options)) === 'array') {
                $this->is_group = true;
                $this->body[] = $this->addFormItem($options);
                $this->is_group = false;
            } else {
                $this->addFormItem(...$options);
            }
        }
        return $this;
    }
    /**
     * 判断数组是否为关联数组
     * @param array $arr
     * @return bool
     */
    private function isIndexedArray(array $arr): bool
    {
        if (empty($arr)) {
            return true; // 空数组视为索引数组
        }
        return array_keys($arr) === range(0, count($arr) - 1);
    }
    public function __call($name, $arguments)
    {
        if (strpos($name, 'set') !== false) {

            $name = str_replace('add', '', $name);
            $name = lcfirst($name);
            $this->set($name, ...$arguments);
        }
        return $this;
    }
}
